from werkzeug.security import generate_password_hash, check_password_hash

from common.libs.BaseModel import BaseModel
from sqlalchemy import (
    BigInteger,
    Integer,
    String,
    Boolean,
    Column,
    Enum,
    SmallInteger,
    DateTime,
    Table,
    BIGINT,
    ForeignKey,
    MetaData,
    Text,
)
import json
import math
import logging
from datetime import datetime, timedelta
from . import TABLE_PREFIX


def _format_date(d, f: str = "%Y-%m-%d"):
    if d is None or type(d) is not datetime:
        return ""
    return datetime.strftime(d, f)


LOGGER = logging.getLogger(__name__)


class User(BaseModel):
    class Gender(Enum):
        MAN = 1
        WOMAN = 2
        UNKONW = 3

    __tablename__ = f"{TABLE_PREFIX}user"
    __table_args__ = {"comment": "后台用户表"}

    openPlatform = Column(String(10), default="wx", comment="openid 的平台")
    openId = Column(String(50), comment="微信openId或者gg的id，fb的id", unique=True)
    accessToken = Column(String(256), comment="accessToken")
    refreshToken = Column(String(256), comment="refreshToken")
    nickname = Column(String(100), comment="昵称")
    headimg = Column(String(256), comment="头像")

    username = Column(String(50), comment="登录账号", unique=True)
    password_hash = Column(Text(65536), comment="密码")
    realname = Column(String(100), comment="真实姓名")
    phone = Column(String(100), comment="电话")

    gender = Column(SmallInteger, default=Gender.UNKONW, comment="性别")
    email = Column(String(100), comment="邮箱")
    is_lock = Column(Boolean, nullable=False, default=False, comment="是否锁定")
    last_login_time = Column(String(100), comment="最后登录时间")
    last_login_ip = Column(String(100), comment="最后登录ip")
    vip_level = Column(Integer, comment="会员等级", default=1)
    vip_start_at = Column(DateTime, comment="开始时间")
    vip_expire_at = Column(DateTime, comment="结束时间")

    balance = Column(Integer, comment="余额")
    invite_code = Column(String(20), comment="邀请码")
    from_user_id = Column(BigInteger(), comment="邀请人")

    def isVip(self):
        now = datetime.now()

        if self.vip_start_at is None or self.vip_expire_at is None:
            return False

        if now >= self.vip_start_at and now <= self.vip_expire_at:
            return True

        return False

    def extendVip(self, day: int = 1, hour: int = 0):
        LOGGER.info(f"扩展vip期限：uid{self.id} day {day} hour{hour}")
        now = datetime.now()
        if self.vip_start_at is None:
            self.vip_start_at = now

        if self.isVip():
            self.vip_expire_at = (
                self.vip_expire_at + timedelta(days=day) + timedelta(hours=hour)
            )
        else:
            self.vip_expire_at = now + timedelta(days=day) + timedelta(hours=hour)

        self.save()

    @property
    def password(self):
        return ArithmeticError("password 字段不可读")

    @password.setter
    def password(self, raw_password):
        self.password_hash = generate_password_hash(raw_password)

    def check_password(self, raw_password):
        result = check_password_hash(self.password_hash, raw_password)
        return result

    def get_info(self):
        NOW = datetime.now()
        vip_balance_days = ""
        if self.vip_expire_at is not None and self.vip_expire_at > NOW:
            delta = self.vip_expire_at - NOW
            if delta.days > 0:
                vip_balance_days = f"{delta.days+1}天"
            else:
                vip_balance_days = f"{math.ceil(delta.seconds / 3600)}时"

        return {
            "id": self.id,
            "username": self.username if self.username is not None else self.nickname,
            "openId": self.openId,
            "realname": self.realname,
            "phone": self.phone,
            "gender": self.gender,
            "headimg": self.headimg,
            "email": self.email,
            "is_lock": self.is_lock,
            "isLock": self.is_lock,
            "last_login_time": self.last_login_time,
            "last_login_ip": self.last_login_ip,
            "vip_level": self.vip_level,
            "isVip": self.isVip(),
            "vip_start_at": _format_date(self.vip_start_at),
            "vip_start_at_full": _format_date(self.vip_start_at, "%Y-%m-%d %H:%M:%S"),
            "vip_expire_at": _format_date(self.vip_expire_at),
            "vip_expire_at_full": _format_date(self.vip_expire_at, "%Y-%m-%d %H:%M:%S"),
            "vip_balance_days": vip_balance_days,
            "balance": self.balance,
            "invite_code": 'xxx',
            "create_time": _format_date(self.create_time),
            "create_time_full": _format_date(self.create_time, "%Y-%m-%d %H:%M:%S"),
        }

    def __repr__(self):
        return json.dumps(self.to_json())

    def __str__(self):
        return json.dumps(self.to_json())
